package com.likou.math;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

@AllArgsConstructor
@Getter
@Setter
public class KmainsNode {
    private String name;
    private double x;
    private double y;

    public double distance(KmainsNode kmainsNode){
        return Math.sqrt(Math.pow(kmainsNode.x-this.x,2)+Math.pow(kmainsNode.y-this.y,2));
    }

    public KmainsNode minDistance(KmainsNode[] kmainsNodes){
        if(kmainsNodes.length==1)
            return kmainsNodes[0];
        int result =0;
        for (int i =1;i<kmainsNodes.length;i++){
            if(this.distance(kmainsNodes[result])>this.distance(kmainsNodes[i])){
                result = i;
            }
        }
        return kmainsNodes[result];
    }

    public boolean minDistance(KmainsNode[] kmainsNodes,KmainsNode kmainsNode){
        if (!Arrays.asList(kmainsNodes).contains(kmainsNode))
            return false;
        if(kmainsNodes.length==1)
            return true;
        for (int i =1;i<kmainsNodes.length;i++){
            if(this.distance(kmainsNode)>this.distance(kmainsNodes[i])){
                return false;
            }
        }
        return true;
    }

    public static double distance(KmainsNode kmainsNode1,KmainsNode kmainsNode2){
        return Math.sqrt(Math.pow(kmainsNode1.x-kmainsNode2.x,2)+Math.pow(kmainsNode1.y-kmainsNode2.y,2));
    }

    public static KmainsNode avg(List<KmainsNode> kmainsNodes,String name){
        AtomicReference<Double> tempX = new AtomicReference<>((double) 0);
        AtomicReference<Double> tempY = new AtomicReference<>((double) 0);
        kmainsNodes.forEach(kmainsNode->{
            tempX.set(tempX.get() + kmainsNode.getX() / kmainsNodes.size());
            tempY.set(tempY.get() + kmainsNode.getY() / kmainsNodes.size());
        });
        return new KmainsNode(name,tempX.get(),tempY.get());
    }
    @Override
    public String toString() {
        final StringBuffer sb = new StringBuffer("KmainsNode{");
        sb.append("name='").append(name).append('\'');
        sb.append(", x=").append(x);
        sb.append(", y=").append(y);
        sb.append('}');
        return sb.toString();
    }

    public boolean attributeEquals(List<KmainsNode> kmainsNodes,String name){
        if(kmainsNodes.size()==0)
            return true;
        KmainsNode kmainsNode = avg(kmainsNodes,name);
        return this.x == kmainsNode.x&&this.y==kmainsNode.y;
    }
}
